/**
 * @(#)SocialManagerK.java
 *
 * Copyright (c) 2005-2010 PsiqueWare S.A. de C.V. All Rights Reserved.
 * This software is the proprietary information PsiqueWare S.A. de C.V.
 * Use is subject to license terms.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 * <br/>Usuario : &Aacute;ngel El&eacute;ctrico
 * <br/>Creación:
 * <br/>
 * <br/>
 * <br/><t5>Cambios :</t5>
 * <br/><b>Fecha | Autor  |  Cambios</b>
 * <ul>
 * <li> | <a href = "mailto:AngelElectrico@PsiqueWare.com">&Aacute;ngel El&eacute;ctrico</a> | Creaci&oacute;n del Objeto.</li>
 *
 * </ul>
 */
package com.psiqueware.alheli.id.manager;

import com.psiqueware.alheli.dao.DAOException;
import com.psiqueware.alheli.dao.EnlaceTransaccional;
import com.psiqueware.alheli.exception.NullArgumentException;
import com.psiqueware.alheli.id.IdManagerFactory;
import com.psiqueware.alheli.id.PerfilSocial;
import com.psiqueware.alheli.id.Usuario;
import com.psiqueware.alheli.id.UsuariosManager;
import com.psiqueware.alheli.id.dao.IdDAOFactory;
import com.psiqueware.alheli.id.modelo.PerfilSocialK;
import com.psiqueware.alheli.id.modelo.UsuarioK;
import com.psiqueware.alheli.logging.Logger;
import com.psiqueware.alheli.logging.LoggerFactory;
import com.psiqueware.alheli.manager.BaseManager;
import com.psiqueware.alheli.manager.ManagerException;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;

/**
 * Administrador de las identificaciones sociales.
 * <br/>Paquete Original: com.psiqueware.alheli.id.manager
 * <br/>Nombre  Original: SocialManagerK
 * <br/><a href="SocialManagerK.java.html"><i>Ver C&oacute;digo Fuente</i> </a>
 *
 * @author <a href="mailto:AngelElectrico@PsiqueWare.com">Angel El&eacute;ctrico</a>
 * @version Revision: 1.0
 */
public class SocialManagerK extends BaseManager implements com.psiqueware.alheli.id.SocialManager
{
    /**
     * Logger de clase para SocialManagerK
     */
    private static final Logger s_log = LoggerFactory.getLogger(SocialManagerK.class);

    /**
     * Devuelve un {@link PerfilSocial} a partir de su identificador &uacute;nico.
     *
     * @param id                  Identificador &uacute;nico del {@link PerfilSocial}.
     * @param enlaceTransaccional enlace para hacer at&oacute;micas las transacciones.
     *
     * @return {@link PerfilSocial} en caso de encontrarse; <code>null</code> en caso contrario.
     *
     * @throws ManagerException En caso de un error.
     */
    @Override
    public PerfilSocial buscaPerfilSocialPorId(final Long id, final EnlaceTransaccional enlaceTransaccional) throws ManagerException
    {
        try
        {
            return IdDAOFactory.findDAOPerfilSocial(enlaceTransaccional).findPerfilSocialPorId(id, enlaceTransaccional);
        }
        catch (final Exception e)
        {
            final String error = "<error><msg>No se pudo localizar el PerfilSocial</msg><parametros>" + id + "</parametros></error>";
            s_log.error(error);
            s_log.error(e);
            enlaceTransaccional.rollBack();
            throw new ManagerException(error, e);
        }
    }

    /**
     * Agrega un nuevo {@link PerfilSocial} al {@link Usuario}.
     *
     * @param usuario                {@link Usuario} al cual pertenece este {@link PerfilSocial}. <br/> En Spring Social userId: {@link Usuario#getIdentificacion()} usando <code>idUsuario</code> para llegar.
     * @param identificacionSocial   Nombre de usuario en la aplicaci&oacute;n remota. <br/> En Spring Social providerUserId: <code>identificacionSocial</code>.
     * @param prioridad              Prioridad que indica que si el usuario tiene m&uacute;ltiples conexiones cu&aacute;l se usar&aacute; primero. <br/> En Spring Social rank: <code>prioridad</code>.
     * @param direccionPerfil        Cadena con la {@link java.net.URI} que apunta al perfil social. <br/> En Spring Social profileUrl: direccionPerfil.
     * @param direccionImagen        imageUrl: direccionImagen.
     * @param identificacionRemota   accessToken: identificacionRemota.
     * @param autentificacionRemota  secret: autentificacionRemota.
     * @param identificacionRefresco refreshToken: identificacionRefresco.
     * @param expiracion             expireTime: expiracion.
     * @param enlaceTransaccional    Enlace para hacer at&oacute;micas las trasacciones.
     *
     * @return El nuevo {@link PerfilSocial}.
     *
     * @throws ManagerException En caso de un error.
     */
    @Override
    public PerfilSocial nuevoPerfilSocial(final Usuario usuario, final String identificacionSocial, final int prioridad, final String direccionPerfil, final String direccionImagen, final String identificacionRemota, final char[] autentificacionRemota, final String identificacionRefresco, final long expiracion, final EnlaceTransaccional enlaceTransaccional) throws ManagerException
    {
        if (null == usuario)
            throw new NullArgumentException("<error>El argumento 'usuario' no puede ser NULL.</error>");
        if (null == usuario.getId())
            throw new IllegalArgumentException("<error>El argumento 'usuario' deb&iacute;a encontrarse previamente persistido.</error>");

        final UsuariosManager usuariosManager = IdManagerFactory.getUsuariosManager();

        try
        {
            final PerfilSocialK psK = new PerfilSocialK();
            psK.setIdUsuario(usuario.getId());
            psK.setIdentificacionSocial(identificacionSocial);
            psK.setPrioridad(prioridad);
            if (null != direccionPerfil) psK.setDireccionPerfil(new URI(direccionPerfil));
            if (null != direccionImagen) psK.setDireccionImagen(new URI(direccionImagen));
            psK.setIdentificacionRemota(identificacionRemota);
            psK.setAutentificacionRemota(autentificacionRemota);
            psK.setIdentificacionRefresco(identificacionRefresco);
            psK.setExpiracion(expiracion);
            psK.setIdDominio(usuario.getIdDominio());
            IdDAOFactory.findDAOPerfilSocial(enlaceTransaccional).savePerfilSocial(psK, enlaceTransaccional);

            final Long idDominio = psK.getIdDominio();
            if (null != idDominio) psK.setDominio(usuariosManager.buscaDominioPorId(idDominio, enlaceTransaccional));

            return psK;
        }
        catch (URISyntaxException e)
        {
            final String error = "<error><msg>No se pudo crear la URI desde las direcciones sociales.</msg><parametros>" + direccionPerfil + "," + direccionImagen + "</parametros></error>";
            s_log.error(error);
            s_log.error(e);
            enlaceTransaccional.rollBack();
            throw new ManagerException(error, e);
        }
        catch (DAOException e)
        {
            final String error = "<error><msg>No se pudo persistir el PerfilSocial.</msg><parametros>" + usuario + "</parametros></error>";
            s_log.error(error);
            s_log.error(e);
            enlaceTransaccional.rollBack();
            throw new ManagerException(error, e);
        }
    }

    /**
     * Actualiza los datos del {@link PerfilSocial}.
     *
     * @param perfilSocial           A actualizar.
     * @param identificacionSocial   Nombre de usuario en la aplicaci&oacute;n remota. <br/> En Spring Social providerUserId: <code>identificacionSocial</code>.
     * @param prioridad              Prioridad que indica que si el usuario tiene m&uacute;ltiples conexiones cu&aacute;l se usar&aacute; primero. <br/> En Spring Social rank: <code>prioridad</code>.
     * @param direccionPerfil        Cadena con la {@link java.net.URI} que apunta al perfil social. <br/> En Spring Social profileUrl: direccionPerfil.
     * @param direccionImagen        imageUrl: direccionImagen.
     * @param identificacionRemota   accessToken: identificacionRemota.
     * @param autentificacionRemota  secret: autentificacionRemota.
     * @param identificacionRefresco refreshToken: identificacionRefresco.
     * @param expiracion             expireTime: expiracion.
     * @param enlaceTransaccional    Enlace para hacer at&oacute;micas las trasacciones.
     *
     * @throws ManagerException En caso de un error.
     */
    @Override
    public void actualizaPerfilSocial(final PerfilSocial perfilSocial, final String identificacionSocial, final int prioridad, final String direccionPerfil, final String direccionImagen, final String identificacionRemota, final char[] autentificacionRemota, final String identificacionRefresco, final long expiracion, final EnlaceTransaccional enlaceTransaccional) throws ManagerException
    {
        if (null == perfilSocial)
            throw new NullArgumentException("<error>El argumento 'perfilSocial' no puede ser NULL.</error>");
        if (null == perfilSocial.getId())
            throw new IllegalArgumentException("<error>El argumento 'perfilSocial' deb&iacute;a encontrarse previamente persistido.</error>");

        try
        {
            final PerfilSocialK psK = (PerfilSocialK) perfilSocial;
            psK.setIdentificacionSocial(identificacionSocial);
            psK.setPrioridad(prioridad);
            if (null != direccionPerfil) psK.setDireccionPerfil(new URI(direccionPerfil));
            if (null != direccionImagen) psK.setDireccionImagen(new URI(direccionImagen));
            psK.setIdentificacionRemota(identificacionRemota);
            psK.setAutentificacionRemota(autentificacionRemota);
            psK.setIdentificacionRefresco(identificacionRefresco);
            psK.setExpiracion(expiracion);

            IdDAOFactory.findDAOPerfilSocial(enlaceTransaccional).updatePerfilSocial(psK, enlaceTransaccional);
        }
        catch (URISyntaxException e)
        {
            final String error = "<error><msg>No se pudo crear la URI desde las direcciones sociales.</msg><parametros>" + direccionPerfil + "," + direccionImagen + "</parametros></error>";
            s_log.error(error);
            s_log.error(e);
            enlaceTransaccional.rollBack();
            throw new ManagerException(error, e);
        }
        catch (DAOException e)
        {
            final String error = "<error><msg>No se pudo persistir el PerfilSocial.</msg><parametros>" + perfilSocial + "</parametros></error>";
            s_log.error(error);
            s_log.error(e);
            enlaceTransaccional.rollBack();
            throw new ManagerException(error, e);
        }
    }

    /**
     * Carga el conjunto de {@link PerfilSocial} asociados con el {@link Usuario}.
     *
     * @param usuario             Cuyos {@link PerfilSocial} es necesario cargar.
     * @param enlaceTransaccional Enlace para hacer at&oacute;micas las trasacciones.
     *
     * @return <code>true</code> si existen {@link PerfilSocial} asociados al {@link Usuario}; <code>false</code> en caso contrario.
     *
     * @throws ManagerException En caso de un error.
     */
    @Override
    public boolean cargaPerfilesSociales(final Usuario usuario, final EnlaceTransaccional enlaceTransaccional) throws ManagerException
    {
        if (null == usuario)
            throw new NullArgumentException("<error>El argumento 'usuario' no puede ser NULL.</error>");
        if (null == usuario.getId())
            throw new IllegalArgumentException("<error>El argumento 'usuario' deb&iacute;a encontrarse previamente persistido.</error>");

        try
        {
            final UsuariosManager usuariosManager = IdManagerFactory.getUsuariosManager();
            final List<PerfilSocial> perfiles = IdDAOFactory.findDAOPerfilSocial(enlaceTransaccional).listPerfilSocialPorIdUsuario(usuario.getId(), enlaceTransaccional);
            for (final PerfilSocial perfilSocial : perfiles)
            {
                final PerfilSocialK psK = (PerfilSocialK) perfilSocial;
                final Long idDominio = psK.getIdDominio();
                if (null != idDominio)
                    psK.setDominio(usuariosManager.buscaDominioPorId(idDominio, enlaceTransaccional));
            }
            final UsuarioK uK = (UsuarioK) usuario;
            uK.setPerfiles(perfiles);
            return !perfiles.isEmpty();
        }
        catch (DAOException e)
        {
            final String error = "<error><msg>No se pudieron cargar los Perfiles.</msg><parametros>" + usuario + "</parametros></error>";
            s_log.error(error);
            s_log.error(e);
            enlaceTransaccional.rollBack();
            throw new ManagerException(error, e);
        }
    }

    /**
     * Elimina un {@link PerfilSocial}.
     *
     * @param perfilSocial        A eliminar.
     * @param enlaceTransaccional Enlace para hacer at&oacute;micas las trasacciones.
     *
     * @throws ManagerException En caso de un error.
     */
    public void eliminarPerfilSocial(final PerfilSocial perfilSocial, final EnlaceTransaccional enlaceTransaccional) throws ManagerException
    {
        try
        {
            IdDAOFactory.findDAOPerfilSocial(enlaceTransaccional).deletePerfilSocial(perfilSocial, enlaceTransaccional);
        }
        catch (DAOException e)
        {
            final String error = "<error><msg>No se pudo eliminar el PerfilSocial</msg><parametros>" + perfilSocial + "</parametros></error>";
            s_log.error(error);
            s_log.error(e);
            enlaceTransaccional.rollBack();
            throw new ManagerException(error, e);
        }
    }
}
